home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 85 / CD Temático 40 Febrero 2004.iso / DOS / testdisk / src / fat.c < prev    next >
Encoding:
C/C++ Source or Header  |  2004-01-09  |  29.1 KB  |  880 lines

  1. /*
  2.  
  3.     File: fat.c
  4.  
  5.     Copyright (C) 1998-2004 Christophe GRENIER <grenier@cgsecurity.org>
  6.   
  7.     This software is free software; you can redistribute it and/or modify
  8.     it under the terms of the GNU General Public License as published by
  9.     the Free Software Foundation; either version 2 of the License, or
  10.     (at your option) any later version.
  11.   
  12.     This program is distributed in the hope that it will be useful,
  13.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.     GNU General Public License for more details.
  16.   
  17.     You should have received a copy of the GNU General Public License
  18.     along with this program; if not, write to the Free Software
  19.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20.  
  21.  */
  22.  
  23. #include <stdio.h>
  24. #include <ctype.h>    /* toupper */
  25. #include <string.h>
  26. #include <stdlib.h>
  27. #include <time.h>
  28. #include "types.h"
  29. #include "common.h"
  30. #include "fat.h"
  31. #include "lang.h"
  32. #include "fnctdsk.h"
  33. #include "testdisk.h"
  34. #include "intrface.h"
  35.  
  36. static int set_FAT_info(t_param_disk *disk_car, const struct fat_boot_sector *fat_header, t_diskext *partition,const int debug);
  37.  
  38. int dump_fat_rapport(const struct fat_boot_sector*fh1, const upart_type_t upart_type)
  39. {
  40.   ecrit_rapport("sector_size  %u\n", sector_size(fh1));
  41.   ecrit_rapport("cluster_size %u\n", fh1->cluster_size);
  42.   ecrit_rapport("reserved     %u\n", le16(fh1->reserved));
  43.   ecrit_rapport("fats         %u\n", fh1->fats);
  44.   ecrit_rapport("dir_entries  %u\n", get_dir_entries(fh1));
  45.   ecrit_rapport("sectors      %u\n", sectors(fh1));
  46.   ecrit_rapport("media        %02X\n", fh1->media);
  47.   ecrit_rapport("fat_length   %u\n", le16(fh1->fat_length));
  48.   ecrit_rapport("secs_track   %u\n", le16(fh1->secs_track));
  49.   ecrit_rapport("heads        %u\n", le16(fh1->heads));
  50.   ecrit_rapport("hidden       %u\n", le32(fh1->hidden));
  51.   ecrit_rapport("total_sect   %u\n", le32(fh1->total_sect));
  52.   if(upart_type==UP_FAT32)
  53.   {
  54.       ecrit_rapport("fat32_length %u\n", le32(fh1->fat32_length));
  55.       ecrit_rapport("flags        %04X\n", le16(fh1->flags));
  56.       ecrit_rapport("version      %u.%u\n", fh1->version[0], fh1->version[1]);
  57.       ecrit_rapport("root_cluster %u\n", le32(fh1->root_cluster));
  58.       ecrit_rapport("info_sector  %u\n", le16(fh1->info_sector));
  59.       ecrit_rapport("backup_boot  %u\n", le16(fh1->backup_boot));
  60.       ecrit_rapport("free_count   %lu\n",get_free_count((const unsigned char*)fh1));
  61.       ecrit_rapport("next_free    %lu\n",get_next_free((const unsigned char*)fh1));
  62.   }
  63.   return 0;
  64. }
  65.  
  66. int dump_fat_info(const struct fat_boot_sector*fh1, const upart_type_t upart_type)
  67. {
  68.   switch(upart_type)
  69.   {
  70.     case UP_FAT12:
  71.       wdoprintf(stdscr,"FAT : 12\n");
  72.       break;
  73.     case UP_FAT16:
  74.       wdoprintf(stdscr,"FAT : 16\n");
  75.       break;
  76.     case UP_FAT32:
  77.       wdoprintf(stdscr,"FAT : 32\n");
  78.       break;
  79.     default:
  80.       wdoprintf(stdscr,"Not a FAT\n");
  81.       return 0;
  82.   }
  83.   wdoprintf(stdscr,"cluster_size %u\n", fh1->cluster_size);
  84.   wdoprintf(stdscr,"reserved     %u\n", le16(fh1->reserved));
  85.   if(sectors(fh1)!=0)
  86.     wdoprintf(stdscr,"sectors      %u\n", sectors(fh1));
  87.   if(le32(fh1->total_sect)!=0)
  88.     wdoprintf(stdscr,"total_sect   %u\n", le32(fh1->total_sect));
  89.   if(upart_type==UP_FAT32)
  90.   {
  91.     wdoprintf(stdscr,"fat32_length %u\n", le32(fh1->fat32_length));
  92.     wdoprintf(stdscr,"root_cluster %u\n", le32(fh1->root_cluster));
  93.     wdoprintf(stdscr,"flags        %04X\n", le16(fh1->flags));
  94.     wdoprintf(stdscr,"version      %u.%u\n", fh1->version[0], fh1->version[1]);
  95.     wdoprintf(stdscr,"root_cluster %u\n", le32(fh1->root_cluster));
  96.     wdoprintf(stdscr,"info_sector  %u\n", le16(fh1->info_sector));
  97.     wdoprintf(stdscr,"backup_boot  %u\n", le16(fh1->backup_boot));
  98.     wdoprintf(stdscr,"free_count   %lu\n",get_free_count((const unsigned char*)fh1));
  99.     wdoprintf(stdscr,"next_free    %lu\n",get_next_free((const unsigned char*)fh1));
  100.   } else {
  101.     wdoprintf(stdscr,"fat_length   %u\n", le16(fh1->fat_length));
  102.     wdoprintf(stdscr,"dir_entries  %u\n", get_dir_entries(fh1));
  103.   }
  104.   return 0;
  105. }
  106.  
  107. int dump_2fat_info(const struct fat_boot_sector*fh1, const struct fat_boot_sector*fh2, const upart_type_t upart_type)
  108. {
  109.   switch(upart_type)
  110.   {
  111.     case UP_FAT12:
  112.       wdoprintf(stdscr,"FAT : 12\n");
  113.       break;
  114.     case UP_FAT16:
  115.       wdoprintf(stdscr,"FAT : 16\n");
  116.       break;
  117.     case UP_FAT32:
  118.       wdoprintf(stdscr,"FAT : 32\n");
  119.       break;
  120.     default:
  121.       wdoprintf(stdscr,"Not a FAT\n");
  122.       return 0;
  123.   }
  124.   wdoprintf(stdscr,"cluster_size %u %u\n", fh1->cluster_size, fh2->cluster_size);
  125.   wdoprintf(stdscr,"reserved     %u %u\n", le16(fh1->reserved),le16(fh2->reserved));
  126.   if(sectors(fh1)!=0 || sectors(fh2)!=0)
  127.     wdoprintf(stdscr,"sectors      %u %u\n", sectors(fh1), sectors(fh2));
  128.   if(le32(fh1->total_sect)!=0 || le32(fh2->total_sect)!=0)
  129.     wdoprintf(stdscr,"total_sect   %u %u\n", le32(fh1->total_sect), le32(fh2->total_sect));
  130.   if(upart_type==UP_FAT32)
  131.   {
  132.     wdoprintf(stdscr,"fat32_length %u %u\n", le16(fh1->fat32_length), le16(fh2->fat32_length));
  133.     wdoprintf(stdscr,"root_cluster %u %u\n", le32(fh1->root_cluster), le32(fh2->root_cluster));
  134. /*  wdoprintf(stdscr,"free_count   %lu %lu\n",get_free_count((const unsigned char*)fh1),get_free_count((const unsigned char*)fh2));
  135.     wdoprintf(stdscr,"next_free    %lu %lu\n",get_next_free((const unsigned char*)fh1),get_next_free((const unsigned char*)fh2));
  136.     */
  137.   } else {
  138.     wdoprintf(stdscr,"fat_length   %u %u\n", le16(fh1->fat_length), le16(fh2->fat_length));
  139.     wdoprintf(stdscr,"dir_entries  %u %u\n", get_dir_entries(fh1), get_dir_entries(fh2));
  140.   }
  141.   return 0;
  142. }
  143.  
  144. int dump_fat_info_rapport(const struct fat_boot_sector*fh1, const upart_type_t upart_type)
  145. {
  146.   ecrit_rapport("cluster_size %u\n", fh1->cluster_size);
  147.   ecrit_rapport("reserved     %u\n", le16(fh1->reserved));
  148.   if(sectors(fh1)!=0)
  149.     ecrit_rapport("sectors      %u\n", sectors(fh1));
  150.   if(le32(fh1->total_sect)!=0)
  151.     ecrit_rapport("total_sect   %u\n", le32(fh1->total_sect));
  152.   if(upart_type==UP_FAT32)
  153.   {
  154.     ecrit_rapport("fat32_length %u\n", le32(fh1->fat32_length));
  155.     ecrit_rapport("root_cluster %u\n", le32(fh1->root_cluster));
  156.     ecrit_rapport("free_count   %lu\n",get_free_count((const unsigned char*)fh1));
  157.     ecrit_rapport("next_free    %lu\n",get_next_free((const unsigned char*)fh1));
  158.   } else {
  159.     ecrit_rapport("fat_length   %u\n", le16(fh1->fat_length));
  160.     ecrit_rapport("dir_entries  %u\n", get_dir_entries(fh1));
  161.   }
  162.   return 0;
  163. }
  164.  
  165. int dump_2fat_rapport(const struct fat_boot_sector*fh1, const struct fat_boot_sector*fh2, const upart_type_t upart_type)
  166. {
  167.   switch(upart_type)
  168.   {
  169.     case UP_FAT12:
  170.       ecrit_rapport("\nFAT12");
  171.       break;
  172.     case UP_FAT16:
  173.       ecrit_rapport("\nFAT16");
  174.       break;
  175.     case UP_FAT32:
  176.       ecrit_rapport("\nFAT32");
  177.       break;
  178.     default:
  179.       return 1;
  180.   }
  181.   ecrit_rapport("\nsector_size  %u %u", sector_size(fh1),sector_size(fh2));
  182.   ecrit_rapport("\ncluster_size %u %u", fh1->cluster_size,fh2->cluster_size);
  183.   ecrit_rapport("\nreserved     %u %u", le16(fh1->reserved),le16(fh2->reserved));
  184.   ecrit_rapport("\nfats         %u %u", fh1->fats,fh2->fats);
  185.   ecrit_rapport("\ndir_entries  %u %u", get_dir_entries(fh1),get_dir_entries(fh2));
  186.   ecrit_rapport("\nsectors      %u %u", sectors(fh1),sectors(fh2));
  187.   ecrit_rapport("\nmedia        %02X %02X", fh1->media,fh2->media);
  188.   ecrit_rapport("\nfat_length   %u %u", le16(fh1->fat_length),le16(fh2->fat_length));
  189.   ecrit_rapport("\nsecs_track   %u %u", le16(fh1->secs_track),le16(fh2->secs_track));
  190.   ecrit_rapport("\nheads        %u %u", le16(fh1->heads),le16(fh2->heads));
  191.   ecrit_rapport("\nhidden       %u %u", le32(fh1->hidden),le32(fh2->hidden));
  192.   ecrit_rapport("\ntotal_sect   %u %u", le32(fh1->total_sect),le32(fh2->total_sect));
  193.   if(upart_type==UP_FAT32)
  194.   {
  195.     ecrit_rapport("\nfat32_length %u %u", le32(fh1->fat32_length),le32(fh2->fat32_length));
  196.     ecrit_rapport("\nflags        %04X %04X", le16(fh1->flags),le16(fh2->flags));
  197.     ecrit_rapport("\nversion      %u.%u  %u.%u", fh1->version[0], fh1->version[1],fh2->version[0], fh2->version[1]);
  198.     ecrit_rapport("\nroot_cluster %u %u", le32(fh1->root_cluster),le32(fh2->root_cluster));
  199.     ecrit_rapport("\ninfo_sector  %u %u", le16(fh1->info_sector),le16(fh2->info_sector));
  200.     ecrit_rapport("\nbackup_boot  %u %u", le16(fh1->backup_boot),le16(fh2->backup_boot));
  201.     ecrit_rapport("\nfree_count   %lu %lu",get_free_count((const unsigned char*)fh1),get_free_count((const unsigned char*)fh2));
  202.     ecrit_rapport("\nnext_free    %lu %lu",get_next_free((const unsigned char*)fh1),get_next_free((const unsigned char*)fh2));
  203.   }
  204.   ecrit_rapport("\n");
  205.   return 0;
  206. }
  207.  
  208. int check_FAT(t_param_disk *disk_car,t_diskext *partition,const int debug)
  209. {
  210.   t_sector buffer;
  211.   if(disk_car->read(disk_car,1, &buffer, partition->lba)!=0)
  212.   {
  213.     aff_buffer(BUFFER_ADD,msg_CHKFAT_RERR);
  214.     ecrit_rapport(msg_CHKFAT_RERR);
  215.     return 1;
  216.   }
  217.   if(test_FAT(disk_car,(const struct fat_boot_sector *)buffer,partition,debug,0)!=0)
  218.   {
  219.     if(debug!=0)
  220.     {
  221.       ecrit_rapport("\n\ntest_FAT()\n");
  222.       aff_part_rapport(disk_car,partition);
  223.       dump_fat_rapport((const struct fat_boot_sector*)buffer, partition->upart_type);
  224.     }
  225.     return 1;
  226.   }
  227.   set_FAT_info(disk_car,(const struct fat_boot_sector *)buffer,partition,debug);
  228. /*  aff_buffer(BUFFER_ADD,"Ok\n"); */
  229.   return 0;
  230. }
  231.  
  232. static int set_FAT_info(t_param_disk *disk_car, const struct fat_boot_sector *fat_header, t_diskext *partition,const int debug)
  233. {
  234.   partition->name[0]=0;
  235.   switch(partition->upart_type)
  236.   {
  237.     case UP_FAT12:
  238.     case UP_FAT16:
  239.       set_part_name(partition,((const char*)fat_header)+FAT1X_PART_NAME,11);
  240.       if(check_volume_name(partition->name,11))
  241.     partition->name[0]='\0';
  242.       break;
  243.     case UP_FAT32:
  244.       fat32_set_part_name(disk_car,partition,fat_header);
  245.       break;
  246.     default:
  247.       ecrit_rapport("set_FAT_info unknown upart_type\n");
  248.       return 1;
  249.   }
  250.   return 0;
  251. }
  252.  
  253. dword get_next_cluster(t_param_disk *disk_car,const t_diskext *partition, const upart_type_t upart_type,const int offset, const dword cluster)
  254. {
  255.   /* Offset can be offset to FAT1 or to FAT2 */
  256. /* ecrit_rapport("get_next_cluster(upart_type=%u,offset=%u,cluster=%u\n",upart_type,offset,cluster); */
  257.   switch(upart_type)
  258.   {
  259.     case UP_FAT12:
  260.       {
  261.     unsigned char buffer[0x400];
  262.     dword offset_s,offset_o;
  263.     offset_s=(cluster+cluster/2)/SECTOR_SIZE;
  264.     offset_o=(cluster+cluster/2)%SECTOR_SIZE;
  265.     if(disk_car->read(disk_car,2, &buffer, partition->lba+offset+offset_s)!=0)
  266.     {
  267.       ecrit_rapport("\nget_next_cluster error"); return 0;
  268.     }
  269.     if((cluster&1)!=0)
  270.       return le16((*((__u16*)&buffer[offset_o])))>>4;
  271.     else
  272.       return le16(*((__u16*)&buffer[offset_o]))&0x0FFF;
  273.       }
  274.     case UP_FAT16:
  275.       {
  276.     unsigned char buffer[SECTOR_SIZE];
  277.     __u16 *p16=(__u16*)&buffer;
  278.     dword offset_s,offset_o;
  279.     offset_s=cluster/256;
  280.     offset_o=cluster%256;
  281.     if(disk_car->read(disk_car,1, &buffer, partition->lba+offset+offset_s)!=0)
  282.     {
  283.       ecrit_rapport("\nget_next_cluster error"); return 0;
  284.     }
  285.     return le16(p16[offset_o]);
  286.       }
  287.     case UP_FAT32:
  288.       {
  289.     unsigned char buffer[SECTOR_SIZE];
  290.     __u32 *p32=(__u32*)&buffer;
  291.     dword offset_s,offset_o;
  292.     offset_s=cluster/128;
  293.     offset_o=cluster%128;
  294.     if(disk_car->read(disk_car,1, &buffer, partition->lba+offset+offset_s)!=0)
  295.     {
  296.       ecrit_rapport("\nget_next_cluster error"); return 0;
  297.     }
  298.     /* FAT32 used 28 bits, the 4 high bits are reserved
  299.      * 0x00000000: free cluster
  300.      * 0x0FFFFFF7: bad cluster
  301.      * 0x0FFFFFF8+: EOC End of cluster
  302.      * */
  303.     return le32(p32[offset_o])&0xFFFFFFF;
  304.       }
  305.     default:
  306.       ecrit_rapport("fat.c get_next_cluster unknown fat type\n");
  307.       return 0;
  308.   }
  309. }
  310.  
  311. dword fat32_get_prev_cluster(t_param_disk *disk_car,const t_diskext *partition, const unsigned int fat_offset, const dword cluster, const dword no_of_cluster)
  312. {
  313.   unsigned char buffer[SECTOR_SIZE];
  314.   __u32 *p32=(__u32*)&buffer;
  315.   dword hd_offset=partition->lba+fat_offset;
  316.   dword prev_cluster;
  317.   for(prev_cluster=2;prev_cluster<=no_of_cluster+1;prev_cluster++)
  318.   {
  319.     unsigned int offset_s,offset_o;
  320.     offset_s=prev_cluster/128;
  321.     offset_o=prev_cluster%128;
  322.     if((offset_o==0)||(prev_cluster==2))
  323.     {
  324.       if(disk_car->read(disk_car,1, &buffer, hd_offset++)!=0)
  325.       {
  326.     ecrit_rapport("fat32_get_prev_cluster error\n"); return 0;
  327.       }
  328.     }
  329.     if((le32(p32[offset_o]) & 0xFFFFFFF) ==cluster)
  330.       return prev_cluster;
  331.   }
  332.   return 0;
  333. }
  334.  
  335. dword get_prev_cluster(t_param_disk *disk_car,const t_diskext *partition, const upart_type_t upart_type,const int offset, const dword cluster, const dword no_of_cluster)
  336. {
  337.   dword prev_cluster;
  338.   for(prev_cluster=2;prev_cluster<=no_of_cluster+1;prev_cluster++)
  339.   {
  340.     if(get_next_cluster(disk_car,partition,upart_type,offset, prev_cluster)==cluster)
  341.       return prev_cluster;
  342.   }
  343.   return 0;
  344. }
  345.  
  346. int test_FAT(t_param_disk *disk_car,const struct fat_boot_sector *fat_header, t_diskext *partition,const int debug, const int dump_ind)
  347. {
  348.   dword start_fat1,start_fat2,start_rootdir,start_data,no_of_cluster,fat_length,fat_length_calc,part_size,end_data;
  349.   const char *buffer=(const char*)fat_header;
  350.   if(debug>1)
  351.   {
  352.     ecrit_rapport("test_FAT\n");
  353.     aff_part_rapport(disk_car,partition);
  354.   }
  355.   if(le16(fat_header->marker)!=0xAA55)
  356.   {
  357.     aff_buffer(BUFFER_ADD,"test_FAT : Boot sector doesn't have the endmark 0xAA55\n");
  358.     ecrit_rapport("test_FAT : Boot sector doesn't have the endmark 0xAA55\n");
  359.     return 1;
  360.   }
  361.   if(dump_ind!=0)
  362.     dump(stdscr,fat_header,SECTOR_SIZE);
  363.   if(!((fat_header->ignored[0]==0xeb && fat_header->ignored[2]==0x90)||fat_header->ignored[0]==0xe9))
  364.   {
  365.     aff_buffer(BUFFER_ADD,msg_CHKFAT_BAD_JUMP);
  366.     ecrit_rapport(msg_CHKFAT_BAD_JUMP);
  367.     return 1;
  368.   }
  369.   if(sector_size(fat_header)!=SECTOR_SIZE)
  370.   {
  371.     aff_buffer(BUFFER_ADD,msg_CHKFAT_BYTESECT);
  372.     ecrit_rapport(msg_CHKFAT_BYTESECT);
  373.     return 1;
  374.   }
  375.   switch(fat_header->cluster_size)
  376.   {
  377.     case 1:
  378.     case 2:
  379.     case 4:
  380.     case 8:
  381.     case 16:
  382.     case 32:
  383.     case 64:
  384.     case 128:
  385.       break;
  386.     default:
  387.       aff_buffer(BUFFER_ADD,msg_CHKFAT_SECT_CLUSTER);
  388.       ecrit_rapport(msg_CHKFAT_SECT_CLUSTER);
  389.       return 1;
  390.   }
  391.   if(fat_header->fats!=2)
  392.   {
  393.     aff_buffer(BUFFER_ADD,msg_CHKFAT_NBRFAT);
  394.     ecrit_rapport(msg_CHKFAT_NBRFAT);
  395.     return 1;
  396.   }
  397.   if(fat_header->media!=0xF8)
  398.   {    /* Legal values are 0xF0, 0xF8-0xFF
  399.        but the only value I have ever seen is 0xF8
  400.      */
  401.     aff_buffer(BUFFER_ADD,msg_CHKFAT_MEDIA);
  402.     ecrit_rapport(msg_CHKFAT_MEDIA);
  403.     return 1;
  404.   }
  405.   fat_length=le16(fat_header->fat_length)>0?le16(fat_header->fat_length):le32(fat_header->fat32_length);
  406.   part_size=(sectors(fat_header)>0?sectors(fat_header):fat_header->total_sect);
  407.   start_fat1=le16(fat_header->reserved);
  408.   start_fat2=start_fat1+fat_length;
  409.   start_data=start_fat2+fat_length+(get_dir_entries(fat_header)*32+SECTOR_SIZE-1)/SECTOR_SIZE;
  410.   no_of_cluster=(part_size-start_data)/fat_header->cluster_size;
  411.   end_data=start_data+no_of_cluster*fat_header->cluster_size-1;
  412.   if(no_of_cluster<4085)
  413.   {
  414.     if(debug)
  415.       ecrit_rapport("FAT12\n");
  416.     if(sectors(fat_header)==0)
  417.     {
  418.       aff_buffer(BUFFER_ADD,msg_CHKFAT_SIZE);
  419.       ecrit_rapport(msg_CHKFAT_SIZE);
  420.     }
  421.     if(le16(fat_header->reserved)!=1)
  422.     {
  423.       aff_buffer(BUFFER_ADD,msg_CHKFAT_RESERV);
  424.       ecrit_rapport(msg_CHKFAT_RESERV);
  425.       return 1;
  426.     }
  427.     if((get_dir_entries(fat_header)==0)||(get_dir_entries(fat_header)%16!=0))
  428.     {
  429.       aff_buffer(BUFFER_ADD,msg_CHKFAT_ENTRY);
  430.       ecrit_rapport(msg_CHKFAT_ENTRY);
  431.       return 1;
  432.     }
  433.     if((le16(fat_header->fat_length)>256)||(le16(fat_header->fat_length)==0))
  434.     {
  435.       aff_buffer(BUFFER_ADD,msg_CHKFAT_SECTPFAT);
  436.       ecrit_rapport(msg_CHKFAT_SECTPFAT);
  437.       return 1;
  438.     }
  439.     start_rootdir=start_fat2+fat_length;
  440.     fat_length_calc=((no_of_cluster+2+SECTOR_SIZE*2/3-1)*3/2/SECTOR_SIZE);
  441.     partition->upart_type=UP_FAT12;
  442.     if(memcmp(buffer+FAT_NAME1,"FAT12   ",8)!=0) /* 2 Mo max */
  443.     {
  444.       aff_buffer(BUFFER_ADD,"Should be marked as FAT12\n");
  445.       ecrit_rapport("Should be marked as FAT12\n");
  446.     }
  447.   }
  448.   else if(no_of_cluster<65525)
  449.   {
  450.     if(debug)
  451.       ecrit_rapport("FAT16\n");
  452.     if(le16(fat_header->reserved)!=1)
  453.     {
  454.       aff_buffer(BUFFER_ADD,msg_CHKFAT_RESERV);
  455.       ecrit_rapport(msg_CHKFAT_RESERV);
  456.       return 1;
  457.     }
  458.     if(le16(fat_header->fat_length)==0)
  459.     {
  460.       aff_buffer(BUFFER_ADD,msg_CHKFAT_SECTPFAT);
  461.       ecrit_rapport(msg_CHKFAT_SECTPFAT);
  462.       return 1;
  463.     }
  464.     if((get_dir_entries(fat_header)==0)||(get_dir_entries(fat_header)%16!=0))
  465.     {
  466.       aff_buffer(BUFFER_ADD,msg_CHKFAT_ENTRY);
  467.       ecrit_rapport(msg_CHKFAT_ENTRY);
  468.       return 1;
  469.     }
  470.     start_rootdir=start_fat2+fat_length;
  471.     fat_length_calc=((no_of_cluster+2+SECTOR_SIZE/2-1)*2/SECTOR_SIZE);
  472.     partition->upart_type=UP_FAT16;
  473.     if(memcmp(buffer+FAT_NAME1,"FAT16   ",8)!=0)
  474.     {
  475.       aff_buffer(BUFFER_ADD,"Should be marked as FAT16\n");
  476.       ecrit_rapport("Should be marked as FAT16\n");
  477.     }
  478.   }
  479.   else
  480.   {
  481.     if(debug)
  482.       ecrit_rapport("FAT32\n");
  483.     if(sectors(fat_header)!=0)
  484.     {
  485.       aff_buffer(BUFFER_ADD,msg_CHKFAT_SIZE);
  486.       ecrit_rapport(msg_CHKFAT_SIZE);
  487.       return 1;
  488.     }
  489.     if(get_dir_entries(fat_header)!=0)
  490.     {
  491.       aff_buffer(BUFFER_ADD,msg_CHKFAT_ENTRY);
  492.       ecrit_rapport(msg_CHKFAT_ENTRY);
  493.       return 1;
  494.     }
  495.     if((fat_header->version[0]!=0) || (fat_header->version[1]!=0))
  496.     {
  497.       aff_buffer(BUFFER_ADD,msg_CHKFAT_BADFAT32VERSION);
  498.       ecrit_rapport(msg_CHKFAT_BADFAT32VERSION);
  499.     }
  500.     if((le32(fat_header->root_cluster)<2) ||(le32(fat_header->root_cluster)>=2+no_of_cluster))
  501.     {
  502.       aff_buffer(BUFFER_ADD,"Bad root_cluster\n");
  503.       ecrit_rapport("Bad root_cluster\n");
  504.       return 1;
  505.     }
  506.     start_rootdir=start_data+(le32(fat_header->root_cluster)-2)*fat_header->cluster_size;
  507.     fat_length_calc=((no_of_cluster+2+SECTOR_SIZE/4-1)*4/SECTOR_SIZE);
  508.     partition->upart_type=UP_FAT32;
  509.     if(memcmp(buffer+FAT_NAME2,"FAT32   ",8)!=0)
  510.     {
  511.       aff_buffer(BUFFER_ADD,"Should be marked as FAT32\n");
  512.       ecrit_rapport("Should be marked as FAT32\n");
  513.     }
  514.   }
  515.   if(partition->part_size>0)
  516.   {
  517.     if(part_size>partition->part_size)
  518.     {
  519.       ecrit_rapport("test_FAT size boot_sector %ld > partition %ld\n",part_size,partition->part_size);
  520.       aff_buffer(BUFFER_ADD,msg_CHKFAT_SIZE);
  521.       return 1;
  522.     }
  523.     else
  524.     {
  525.       if((debug>0) && (part_size!=partition->part_size))
  526.     ecrit_rapport("test_FAT size boot_sector %ld, partition %ld\n",part_size,partition->part_size);
  527.     }
  528.   }
  529.   if(debug>0)
  530.   {
  531.     ecrit_rapport("FAT1 : %lu-%lu\n",start_fat1,start_fat1+fat_length-1);
  532.     ecrit_rapport("FAT2 : %lu-%lu\n",start_fat2,start_fat2+fat_length-1);
  533.     ecrit_rapport("start_rootdir : %lu",start_rootdir);
  534.     if(partition->upart_type==UP_FAT32)
  535.       ecrit_rapport(" root cluster : %u",le32(fat_header->root_cluster));
  536.     ecrit_rapport("\nData : %lu-%lu\n",start_data,end_data);
  537.     ecrit_rapport("sectors : %lu\n",part_size);
  538.     ecrit_rapport("cluster_size : %u\n",fat_header->cluster_size);
  539.     ecrit_rapport("no_of_cluster : %lu (2 - %lu)\n", no_of_cluster,no_of_cluster+1);
  540.     ecrit_rapport("fat_length %lu calculated %lu\n",fat_length,fat_length_calc);
  541.   }
  542.   if(fat_length<fat_length_calc)
  543.   { aff_buffer(BUFFER_ADD,msg_CHKFAT_SECTPFAT); return 1; }
  544.   comp_FAT(disk_car,partition,fat_length,le16(fat_header->reserved));
  545.   if(le16(fat_header->secs_track)!=disk_car->CHS.sector)
  546.   {
  547.     aff_buffer(BUFFER_ADD,msg_CHKFAT_SECTTRACK);
  548.     ecrit_rapport("sect/track %u (FAT)!= %u (HD)\n",le16(fat_header->secs_track),disk_car->CHS.sector);
  549.     return 1;
  550.   }
  551.   if(le16(fat_header->heads)!=disk_car->CHS.head+1)
  552.   {
  553.     aff_buffer(BUFFER_ADD,msg_CHKFAT_SIDE);
  554.     ecrit_rapport("heads/cylinder %u (FAT) != %u (HD)\n",le16(fat_header->heads),disk_car->CHS.head+1);
  555.     return 1;
  556.   }
  557.   return 0;
  558. }
  559.  
  560. int comp_FAT(t_param_disk *disk_car,const t_diskext *partition,const dword taille,const dword sect_res)
  561. {
  562.   /*
  563.   return 0 if FATs match
  564.   */
  565.   unsigned int reste=taille;
  566.   unsigned int read_size;
  567.   unsigned char buffer[NBR_SECT*SECTOR_SIZE],buffer2[NBR_SECT*SECTOR_SIZE];
  568.   dword hd_offset, hd_offset2;
  569.   hd_offset=partition->lba+sect_res;
  570.   hd_offset2=hd_offset+taille;
  571.   if(reste>1000) reste=1000;    /* Quick check ! */
  572.   while(reste)
  573.   {
  574.     read_size=reste>NBR_SECT?NBR_SECT:reste;
  575.     reste-=read_size;
  576.     if(disk_car->read(disk_car,read_size, &buffer, hd_offset))
  577.     { ecrit_rapport(msg_CHKFAT_RERR);
  578.       return 1;}
  579.     if(disk_car->read(disk_car,read_size, &buffer2, hd_offset2))
  580.     { ecrit_rapport(msg_CHKFAT_RERR); 
  581.       return 1;}
  582.     if(memcmp(buffer,buffer2,SECTOR_SIZE*read_size)!=0)
  583.     { 
  584.       ecrit_rapport("FAT differs, FAT sectors=%lu-%lu/%lu\n",
  585.     (unsigned long) (hd_offset-(partition->lba+sect_res)),
  586.     (unsigned long) (hd_offset-(partition->lba+sect_res)+read_size),
  587.     taille); 
  588.  
  589.       return 1;
  590.     }
  591.     hd_offset+=read_size;
  592.     hd_offset2+=read_size;
  593.   }
  594.   return 0;
  595. }
  596.  
  597. unsigned int sector_size(const struct fat_boot_sector *fat_header)
  598. { return (fat_header->sector_size[1]<<8)+fat_header->sector_size[0]; }
  599.  
  600. unsigned int get_dir_entries(const struct fat_boot_sector *fat_header)
  601. { return (fat_header->dir_entries[1]<<8)+fat_header->dir_entries[0]; }
  602.  
  603. unsigned int sectors(const struct fat_boot_sector *fat_header)
  604. { return (fat_header->sectors[1]<<8)+fat_header->sectors[0]; }
  605.  
  606. dword get_free_count(const unsigned char *boot_fat32)
  607. {
  608.   return (boot_fat32[0x3E8+3]<<24)+(boot_fat32[0x3E8+2]<<16)+(boot_fat32[0x3E8+1]<<8)+boot_fat32[0x3E8];
  609. }
  610.  
  611. dword get_next_free(const unsigned char *boot_fat32)
  612. {
  613.   return (boot_fat32[0x3EC+3]<<24)+(boot_fat32[0x3EC+2]<<16)+(boot_fat32[0x3EC+1]<<8)+boot_fat32[0x3EC];
  614. }
  615.  
  616. int recover_FAT12(t_param_disk *disk_car,const struct fat_boot_sector*fat_header, t_diskext *partition, const int debug, const int dump_ind)
  617. {
  618.   const char*buffer=(const char*)fat_header;
  619.   if(le16(fat_header->marker)==0xAA55)
  620.   {
  621.     if(memcmp(buffer+FAT_NAME1,"FAT12",5)==0) /* 2 Mo max */
  622.     {
  623.       if(debug||dump_ind)
  624.       {
  625.     ecrit_rapport("\nFAT12 at %u/%u/%u\n", LBA2cylinder(disk_car,partition->lba),LBA2head(disk_car,partition->lba),LBA2sector(disk_car,partition->lba));
  626.       }
  627.       if(test_FAT(disk_car, fat_header, partition, debug, dump_ind))
  628.     return 1;
  629.       partition->part_size=sectors(fat_header);
  630.       partition->part_type=P_12FAT;
  631. /*     partition->upart_type=UP_FAT12;    already done in test_FAT */
  632.       if(buffer[38]==0x29)    /* BS_BootSig */
  633.       {
  634.     set_part_name(partition,buffer+FAT1X_PART_NAME,11);
  635.     if(check_volume_name(partition->name,11))
  636.       partition->name[0]='\0';
  637.       }
  638.       return 0;
  639.     }
  640.   }     /* fin marqueur de fin :)) */
  641.   return 1;
  642. }
  643.  
  644. int recover_FAT16(t_param_disk *disk_car,const struct fat_boot_sector*fat_header, t_diskext *partition, const int debug, const int dump_ind)
  645. {
  646.   const char*buffer=(const char*)fat_header;
  647.   if(le16(fat_header->marker)==0xAA55)
  648.   {
  649.     if(memcmp(buffer+FAT_NAME1,"FAT16",5)==0)
  650.     {
  651.       if(debug||dump_ind)
  652.       {
  653.     ecrit_rapport("\nFAT16 at %u/%u/%u\n", LBA2cylinder(disk_car,partition->lba),LBA2head(disk_car,partition->lba),LBA2sector(disk_car,partition->lba));
  654.       }
  655.       if(test_FAT(disk_car, fat_header, partition, debug, dump_ind))
  656.     return 1;
  657.       if(sectors(fat_header)!=0)
  658.       {
  659.     partition->part_size=sectors(fat_header);
  660.     partition->part_type=P_16FAT;
  661.       } else {
  662.     partition->part_size=le32(fat_header->total_sect);
  663.     if(LBA2cylinder(disk_car,partition->lba+partition->part_size-1)<=1024)
  664.       partition->part_type=P_16FATBD;
  665.     else
  666.       partition->part_type=P_16FATBD_LBA;
  667.       }
  668. /*     partition->upart_type=UP_FAT16;    already done in test_FAT */
  669.       if(buffer[38]==0x29)    /* BS_BootSig */
  670.       {
  671.     set_part_name(partition,buffer+FAT1X_PART_NAME,11);
  672.     if(check_volume_name(partition->name,11))
  673.       partition->name[0]='\0';
  674.       }
  675.       return 0;
  676.     }
  677.   }     /* fin marqueur de fin :)) */
  678.   return 1;
  679. }
  680.  
  681. int recover_FAT32(t_param_disk *disk_car, const struct fat_boot_sector*fat_header, t_diskext *partition, const int debug, const int dump_ind,const int backup)
  682. {
  683.   const char*buffer=(const char*)fat_header;
  684.   if(le16(fat_header->marker)==0xAA55)
  685.   {
  686.     if(memcmp(buffer+FAT_NAME2,"FAT32",5)==0)
  687.     {
  688.       if(debug||dump_ind)
  689.       {
  690.     ecrit_rapport("\nFAT32 at %u/%u/%u\n", LBA2cylinder(disk_car,partition->lba),LBA2head(disk_car,partition->lba),LBA2sector(disk_car,partition->lba));
  691.       }
  692.       if(test_FAT(disk_car, fat_header, partition, debug, dump_ind))
  693.     return 1;
  694.       if(sectors(fat_header)!=0)
  695.     partition->part_size=sectors(fat_header);
  696.       else
  697.     partition->part_size=le32(fat_header->total_sect);
  698.       if(LBA2cylinder(disk_car,partition->lba+partition->part_size-1)<=1024)
  699.     partition->part_type=P_32FAT;
  700.       else
  701.     partition->part_type=P_32FAT_LBA;
  702. /*     partition->upart_type=UP_FAT32;    already done in test_FAT */
  703.       if(backup)
  704.       {
  705.     partition->boot_sector=6;
  706.     partition->lba-=6;    /* backup sector ... */
  707.       }
  708.       fat32_set_part_name(disk_car,partition,fat_header);
  709.       return 0;
  710.     }
  711.   }     /* fin marqueur de fin =:-) */
  712.   return 1;
  713. }
  714.  
  715. int fat32_set_part_name(t_param_disk *disk_car, t_diskext *partition, const struct fat_boot_sector*fat_header)
  716. {
  717.   partition->name[0]='\0';
  718.   if((fat_header->cluster_size>0)&&(fat_header->cluster_size<=128))
  719.   {
  720.     unsigned char *buffer=(unsigned char*)MALLOC(SECTOR_SIZE*fat_header->cluster_size);
  721.     if(disk_car->read(disk_car,fat_header->cluster_size, buffer, partition->lba+le16(fat_header->reserved)+fat_header->fats*le32(fat_header->fat32_length)+(le32(fat_header->root_cluster)-2)*fat_header->cluster_size))
  722.     {
  723.       ecrit_rapport(msg_ROOT_CLUSTER_RERR);
  724.     }
  725.     else
  726.     {
  727.       int i;
  728.       for(i=0;(i<16*fat_header->cluster_size);i++)
  729.       { /* Test attribut volume name and check if the volume name is erased or not */
  730.     if(((buffer[i*0x20+0xB] & ATTR_EXT) !=ATTR_EXT) && ((buffer[i*0x20+0xB] & ATTR_VOLUME) !=0) && (buffer[i*0x20]!=0xE5))
  731.     {
  732.       /*      dump(stdscr,&buffer[i*0x20],0x20); */
  733.       set_part_name(partition,&buffer[i*0x20],11);
  734.       if(check_volume_name(partition->name,11))
  735.         partition->name[0]='\0';
  736.     }
  737.       }
  738.     }
  739.     FREE(buffer);
  740.   }
  741.   if(partition->name[0]=='\0')
  742.   {
  743.     ecrit_rapport("set_FAT_info: name from BS used\n");
  744.     set_part_name(partition,((const char*)fat_header)+FAT32_PART_NAME,11);
  745.     if(check_volume_name(partition->name,11))
  746.       partition->name[0]='\0';
  747.   }
  748.   return 0;
  749. }
  750.  
  751. int recover_HPFS(t_param_disk *disk_car,const struct fat_boot_sector*fat_header, t_diskext *partition, const int debug, const int dump_ind)
  752. {
  753.   const char*buffer=(const char*)fat_header;
  754.   if(le16(fat_header->marker)==0xAA55)
  755.   {
  756.     if(memcmp(buffer+OS2_NAME,"IBM",3)==0)
  757.     {   /* D'apres une analyse de OS2 sur systeme FAT...
  758.        FAT_NAME1=FAT
  759.      */
  760.       if(debug||dump_ind)
  761.       {
  762.     ecrit_rapport("\nHPFS maybe at %u/%u/%u\n", LBA2cylinder(disk_car,partition->lba),LBA2head(disk_car,partition->lba),LBA2sector(disk_car,partition->lba));
  763.       }
  764.       if(dump_ind)
  765.     dump(stdscr,buffer,SECTOR_SIZE);
  766.       if(sectors(fat_header)!=0)
  767.     partition->part_size=sectors(fat_header);
  768.       else
  769.     partition->part_size=le32(fat_header->total_sect);
  770.       partition->part_type=P_HPFS;
  771.       partition->upart_type=UP_HPFS;
  772.       return 0;
  773.     }
  774.   }     /* fin marqueur de fin :)) */
  775.   return 1;
  776. }
  777.  
  778. int recover_OS2MB(t_param_disk *disk_car, const struct fat_boot_sector*fat_header, t_diskext *partition, const int debug, const int dump_ind)
  779. {
  780.   const char*buffer=(const char*)fat_header;
  781.   if(le16(fat_header->marker)==0xAA55)
  782.   {
  783.     if(memcmp(buffer+FAT_NAME1,"FAT     ",8)==0)
  784.     {   /* Attention a detecter apres OS2 */
  785.       if(debug||dump_ind)
  786.       {
  787.     ecrit_rapport("\nMarker (0xAA55) at %u/%u/%u\n", LBA2cylinder(disk_car,partition->lba),LBA2head(disk_car,partition->lba),LBA2sector(disk_car,partition->lba));
  788.       }
  789.       if(dump_ind)
  790.     dump(stdscr,buffer,SECTOR_SIZE);
  791.       partition->part_size=(disk_car->CHS.head+1) * disk_car->CHS.sector; /* 1 cylinder */
  792.       partition->part_type=P_OS2MB;
  793.       partition->upart_type=UP_OS2MB;
  794.       return 0;
  795.     }
  796.   }     /* fin marqueur de fin :)) */
  797.   return 1;
  798. }
  799.  
  800. int is_fat(const int part_type)
  801. {
  802.   return (is_fat12(part_type)||is_fat16(part_type)||is_fat32(part_type));
  803. }
  804.  
  805. int is_fat12(const int part_type)
  806. {
  807.   switch(part_type)
  808.   {
  809.     case P_12FAT:
  810.     case P_12FATH:
  811.       return 1;
  812.   }
  813.   return 0;
  814. }
  815.  
  816. int is_fat16(const int part_type)
  817. {
  818.   switch(part_type)
  819.   {
  820.     case P_16FAT:
  821.     case P_16FATH:
  822.     case P_16FATBD_LBA:
  823.     case P_16FATBD:
  824.     case P_16FATBDH:
  825.     case P_16FATBD_LBAH:
  826.       return 1;
  827.   }
  828.   return 0;
  829. }
  830.  
  831. int is_fat32(const int part_type)
  832. {
  833.   switch(part_type)
  834.   {
  835.     case P_32FAT:
  836.     case P_32FAT_LBA:
  837.     case P_32FATH:
  838.     case P_32FAT_LBAH:
  839.       return 1;
  840.   }
  841.   return 0;
  842. }
  843.  
  844. int fat32_free_info(t_param_disk *disk_car,const t_diskext *partition, const unsigned int fat_offset, const dword no_of_cluster,dword *next_free,dword*free_count)
  845. {
  846.   unsigned char buffer[SECTOR_SIZE];
  847.   __u32 *p32=(__u32*)&buffer;
  848.   dword hd_offset=partition->lba+fat_offset;
  849.   dword prev_cluster;
  850.   *next_free=0;
  851.   *free_count=0;
  852.   for(prev_cluster=2;prev_cluster<=no_of_cluster+1;prev_cluster++)
  853.   {
  854.     dword cluster;
  855.     unsigned int offset_s,offset_o;
  856.     offset_s=prev_cluster/128;
  857.     offset_o=prev_cluster%128;
  858.     if((offset_o==0)||(prev_cluster==2))
  859.     {
  860.       if(disk_car->read(disk_car,1, &buffer, hd_offset++)!=0)
  861.       {
  862.     ecrit_rapport("fat32_get_prev_cluster error\n");
  863.     *next_free=0xFFFFFFFF;
  864.     *free_count=0xFFFFFFFF;
  865.     return 1;
  866.       }
  867.     }
  868.     cluster=le32(p32[offset_o]) & 0xFFFFFFF;
  869.     if(cluster==0)
  870.     {
  871.       (*free_count)++;
  872.       if(*next_free==0)
  873.     *next_free=prev_cluster;
  874.     }
  875.   }
  876.   ecrit_rapport("next_free %ld, free_count %ld\n",*next_free,*free_count);
  877.   return 0;
  878. }
  879.  
  880.